package com.zzc.interview.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzc.interview.annotation.AuthCheck;
import com.zzc.interview.common.BaseResponse;
import com.zzc.interview.common.DeleteRequest;
import com.zzc.interview.common.ErrorCode;
import com.zzc.interview.common.ResultUtils;
import com.zzc.interview.constant.UserConstant;
import com.zzc.interview.exception.BusinessException;
import com.zzc.interview.exception.ThrowUtils;
import com.zzc.interview.model.dto.question.QuestionBatchAddRequest;
import com.zzc.interview.model.dto.question.QuestionBatchDeleteRequest;
import com.zzc.interview.model.dto.question.QuestionBatchRemoveRequest;
import com.zzc.interview.model.dto.questionBank.QuestionBankAddRequest;
import com.zzc.interview.model.dto.questionBank.QuestionBankEditRequest;
import com.zzc.interview.model.dto.questionBank.QuestionBankQueryRequest;
import com.zzc.interview.model.dto.questionBank.QuestionBankUpdateRequest;
import com.zzc.interview.model.dto.questionBankQuestion.QuestionBankQuestionAddRequest;
import com.zzc.interview.model.dto.questionBankQuestion.QuestionBankQuestionUpdateRequest;
import com.zzc.interview.model.entity.Question;
import com.zzc.interview.model.entity.QuestionBank;
import com.zzc.interview.model.entity.QuestionBankQuestion;
import com.zzc.interview.model.entity.User;
import com.zzc.interview.model.vo.QuestionBankVO;
import com.zzc.interview.model.vo.QuestionVO;
import com.zzc.interview.service.QuestionBankQuestionService;
import com.zzc.interview.service.QuestionBankService;
import com.zzc.interview.service.QuestionService;
import com.zzc.interview.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 题库接口
 */
@RestController
@RequestMapping("/questionBankQuestion")
@Slf4j
public class QuestionBankQuestionController {

    @Resource
    private QuestionBankService questionBankService;

    @Resource
    private UserService userService;

    @Resource
    private QuestionBankQuestionService questionBankQuestionService;

    @Resource
    private QuestionService questionService;

    // region 增删改查

    /**
     * 创建题库-题目关联
     *
     * @param questionBankQuestionAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    @SaCheckRole(UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> addQuestionBankQuestion(@RequestBody QuestionBankQuestionAddRequest questionBankQuestionAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(questionBankQuestionAddRequest == null, ErrorCode.PARAMS_ERROR);
        // 数据校验
//        questionBankService.validQuestionBank(questionBank, true);
        // 赋值
        QuestionBankQuestion questionBankQuestion = new QuestionBankQuestion();
        BeanUtil.copyProperties(questionBankQuestionAddRequest, questionBankQuestion);
        User user = (User) request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        questionBankQuestion.setUserId(user.getId());
        // 写入数据库
        boolean result = questionBankQuestionService.save(questionBankQuestion);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        // 返回新写入的数据 id
        long newQuestionBankId = questionBankQuestion.getId();
        return ResultUtils.success(newQuestionBankId);
    }

    /**
     * 创建题库-题目关联
     *
     * @param questionBankQuestionUpdateRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    @SaCheckRole(UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteQuestionBankQuestion(@RequestBody QuestionBankQuestionUpdateRequest questionBankQuestionUpdateRequest, HttpServletRequest request) {
        if (questionBankQuestionUpdateRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 判断是否存在
        QueryWrapper<QuestionBankQuestion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("questionBankId", questionBankQuestionUpdateRequest.getQuestionBankId()).eq("questionId", questionBankQuestionUpdateRequest.getQuestionId());
        QuestionBankQuestion questionBankQuestion = questionBankQuestionService.getOne(queryWrapper);
        ThrowUtils.throwIf(questionBankQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅管理员可删除
        if (!userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 操作数据库
        boolean result = questionBankQuestionService.removeById(questionBankQuestion.getId());
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 批量将题目加入题库
     *
     * @param questionBankQuestionAddRequest
     * @param request
     * @return
     */
    @PostMapping("/batchAddToBank")
    @SaCheckRole(UserConstant.ADMIN_ROLE)
    public BaseResponse<String> batchAddToBank(@RequestBody QuestionBatchAddRequest questionBankQuestionAddRequest, HttpServletRequest request) {
        if (questionBankQuestionAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        List<String> questionIdList = questionBankQuestionAddRequest.getQuestionIdList();
        String questionBankId = questionBankQuestionAddRequest.getQuestionBankId();
        ThrowUtils.throwIf(CollUtil.isEmpty(questionIdList), ErrorCode.PARAMS_ERROR, "题目列表为null");
        ThrowUtils.throwIf(questionBankId == null, ErrorCode.PARAMS_ERROR, "题库id为null");
        // 查询当前题库中已经存在的题目
        LambdaQueryWrapper<QuestionBankQuestion> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QuestionBankQuestion::getQuestionBankId, questionBankId)
                .in(QuestionBankQuestion::getQuestionId, questionIdList);
        List<Long> collect = questionBankQuestionService.list(lambdaQueryWrapper).stream().map(QuestionBankQuestion::getQuestionId).collect(Collectors.toList());
        // 筛除已经存在的题目然后批量保存
        List<QuestionBankQuestion> collect1 = questionIdList.stream().filter(elem -> !collect.contains(elem))
                .map(elem -> {
                    QuestionBankQuestion questionBankQuestion = new QuestionBankQuestion();
                    questionBankQuestion.setQuestionBankId(Long.parseLong(questionBankId));
                    questionBankQuestion.setQuestionId(Long.parseLong(elem));
                    questionBankQuestion.setUserId(userService.getLoginUser(request).getId());
                    return questionBankQuestion;
                }).collect(Collectors.toList());
        questionBankQuestionService.saveBatch(collect1);
        return ResultUtils.success("批量保存成功");
    }

    /**
     * 批量从题库移除题目
     *
     * @param questionBatchRemoveRequest
     * @param request
     * @return
     */
    @PostMapping("/batchRemoveFromBank")
    @SaCheckLogin
    @SaCheckRole(UserConstant.ADMIN_ROLE)
    public BaseResponse<String> batchRemoveFromBank(@RequestBody QuestionBatchRemoveRequest questionBatchRemoveRequest, HttpServletRequest request) {
        if (questionBatchRemoveRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        List<Long> questionIdList = questionBatchRemoveRequest.getQuestionIdList();
        Long questionBankId = questionBatchRemoveRequest.getQuestionBankId();
        ThrowUtils.throwIf(CollUtil.isEmpty(questionIdList), ErrorCode.PARAMS_ERROR, "题目列表为null");
        ThrowUtils.throwIf(questionBankId == null, ErrorCode.PARAMS_ERROR, "题库id为null");
        // 查询当前题库中已经存在的题目
        LambdaQueryWrapper<QuestionBankQuestion> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QuestionBankQuestion::getQuestionBankId, questionBankId)
                .in(QuestionBankQuestion::getQuestionId, questionIdList);
        List<QuestionBankQuestion> list = questionBankQuestionService.list(lambdaQueryWrapper);
        // 如果当前题目在删除列表中，保留，用于批量删除
        List<QuestionBankQuestion> collect = list.stream().filter(elem -> {
            System.out.println(questionIdList.contains(elem.getQuestionId()));
            return questionIdList.contains(elem.getQuestionId());
        }).collect(Collectors.toList());
        questionBankQuestionService.removeBatchByIds(collect);
        return ResultUtils.success("批量移除成功");
    }


    /**
     * 批量从题库移除题目
     *
     * @param questionBatchDeleteRequest
     * @param request
     * @return
     */
    @PostMapping("/batchDeleteQuestion")
    @SaCheckRole(UserConstant.ADMIN_ROLE)
    public BaseResponse<String> batchDeleteQuestion(@RequestBody QuestionBatchDeleteRequest questionBatchDeleteRequest, HttpServletRequest request) {
        if (questionBatchDeleteRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        List<String> questionIdList = questionBatchDeleteRequest.getQuestionIdList();
        ThrowUtils.throwIf(CollUtil.isEmpty(questionIdList), ErrorCode.PARAMS_ERROR, "题目列表为null");
        // 批量删除题目
        boolean ok = questionService.removeBatchByIds(questionIdList);
        // 级联删除关系表
        if (ok) {
            LambdaQueryWrapper<QuestionBankQuestion> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(QuestionBankQuestion::getQuestionId, questionIdList);
            List<QuestionBankQuestion> list = questionBankQuestionService.list(lambdaQueryWrapper);
            questionBankQuestionService.removeBatchByIds(list);
        }
        return ResultUtils.success("批量删除题目成功");
    }

    /**
     * 根据题库id获取题目
     *
     * @param questionBankId
     * @return
     */
    @PostMapping("/getQuestionByBankId")
    public BaseResponse<List<QuestionVO>> getQuestionByBankId(String questionBankId) {
        if (StrUtil.isEmpty(questionBankId)) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<QuestionBankQuestion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("questionBankId", questionBankId);
        List<Long> list = questionBankQuestionService.list(queryWrapper).stream().map(QuestionBankQuestion::getQuestionId).collect(Collectors.toList());
        if (list.isEmpty()) {
            return ResultUtils.success(new ArrayList<>());
        }
        List<QuestionVO> collect = questionService.listByIds(list).stream().map(question -> {
            QuestionVO questionVO = new QuestionVO();
            BeanUtil.copyProperties(question, questionVO);
            return questionVO;
        }).collect(Collectors.toList());
        return ResultUtils.success(collect);
    }

    /**
     * 根据题目id获取题库
     *
     * @param questionId
     * @return
     */
    @PostMapping("/getQuestionBankByQuestionId")
    public BaseResponse<List<QuestionBankVO>> getQuestionBankByQuestionId(String questionId) {
        if (StrUtil.isEmpty(questionId)) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<QuestionBankQuestion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("questionId", questionId);
        List<Long> list = questionBankQuestionService.list(queryWrapper).stream().map(QuestionBankQuestion::getQuestionBankId).collect(Collectors.toList());
        if (list.isEmpty()) {
            return ResultUtils.success(new ArrayList<>());
        }
        List<QuestionBankVO> collect = questionBankService.listByIds(list).stream().map(questionBank -> {
            QuestionBankVO questionBankVO = new QuestionBankVO();
            BeanUtil.copyProperties(questionBank, questionBankVO);
            return questionBankVO;
        }).collect(Collectors.toList());
        return ResultUtils.success(collect);
    }
}
